package byteDance;

import java.util.*;

/*
 * 字节跳动笔试记录
 * 4道题，只看了前三道
 * 1：字符串子串个数问题
 * 		输入给一个字符串，和一个数字代表子串长度，输出该长度的子串在给定字符串中最多有几个
 * 		例：work 2 子串分别有wo wr wk or ok rk 共六个，输出6
 * 2:01字符串翻转问题
 * 		给一个只包含0和1的字符串，再给定几组索引范围，输出经过这几组范围反转后的字符串
 * 		例：4 2（第一个数代表01串长度，第二个数代表有几组索引）
 * 		  0101（01串）
 * 		  1 3（第一组翻转1~3的串，反转后应为1011）
 *        2 2（第二组翻转2~2的串，翻转后应为1111）
 *        最终输出结果：1111
 * 3：绝地求生跳伞跟随问题
 * 		一个队伍中每个人都可以跟随跳伞，给定几组跟随数据，计算经过跟随后队伍中跟随人数最多的一组成员人数，并输出（成员以数字编号）
 * 		例：4 3（4代表队伍共有4人，3代表有三组跟随数据）
 * 		  2 3（第一组数据2跟随3）
 * 		  1 2（第二组数据1跟随2）
 * 		  3 4（第三组数据3跟随4）
 * 		结果：例子中最终形成跟随关系1->2->3->4，所以跟随最大组成员数为4，输出
 * 		上例子为最简单的情况，有可能，一个队最终形成很多组，需要分别比较每一组人数
 * 		我的思路是用一个map将所有成员的跟随情况记录下来，初始化都为1，自己跟随自己算作1，然后要是比如说2->3只需要将key3原本的value加上key2的value
 * 		就形成新的key3的value，最后再找出所有key对应value的最大值，即可
 * 		结果只通过了用例，想了想还有很多问题，觉得应该是用链表做才是正确解法
 */
public class ByteDance {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String s = sc.nextLine();
		String[] ss = s.split(" ");
		int size = Integer.parseInt(ss[0]);
		int line = Integer.parseInt(ss[1]);
		Map<Integer, Integer> map = new HashMap<Integer, Integer>(size);
		for (int i = 1; i <= size; i++) {
			map.put(i, 1);// 初始化，值全部先置1
		}

		int[] sort = new int[line];
		Map<Integer, Integer> kv = new HashMap<Integer, Integer>(line);
		int index = 0;
		while (sc.hasNextInt()) {
			int a = sc.nextInt();
			int b = sc.nextInt();
			sort[index] = b;

			kv.put(b, a);// 无法解决键的重复问题

			index++;// 只要B是按递增顺序就可以用map
		}
		Arrays.sort(sort);
		for (int i = 0; i < line; i++) {
			int b = sort[i];
			int a = kv.get(b);
			map.put(b, map.get(a) + 1);
		}
		/*
		 * while(sc.hasNextInt()){ int a = sc.nextInt(); int b = sc.nextInt();
		 * map.put(b, map.get(a) + 1); }
		 */
		int res = 0;
		// for(MapEntry<Integer, Integer> kv : map.toEntrySet()){
		// if(kv.value > 0){
		// res = kv.value;
		// }
		// }
		for (int i = 1; i <= size; i++) {
			if (map.get(i) > res) {
				res = map.get(i);
			}
		}
		System.out.println(res);
	}

}
